package com.niiwoo.civet.trade.service.local.credit;

import com.alibaba.dubbo.common.utils.Assert;
import com.niiwoo.civet.trade.constant.DatePatternConstant;
import com.niiwoo.civet.trade.constant.enums.CreditRepaymentTypeEnum;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProject;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectDynamic;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectGuarantee;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectInvestor;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectRepayment;
import com.niiwoo.civet.trade.dao.entity.credit.CreditSumProjectRepayment;
import com.niiwoo.civet.trade.dao.mapper.ProjectContractMapperExt;
import com.niiwoo.civet.trade.dao.mapper.credit.*;
import com.niiwoo.civet.trade.dto.request.credit.CreditLoanInvestProjectRequestDTO;
import com.niiwoo.civet.trade.dto.request.creditloan.MyCreditLoanRequestDTO;
import com.niiwoo.civet.trade.dto.response.MyCreditLoanResponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.CreditProjectDynamicReponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.GuaranteeUserDTO;
import com.niiwoo.civet.trade.dto.response.credit.InvestUserDTO;
import com.niiwoo.civet.trade.dto.response.credit.QueryCreditContractReponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.QueryCreditInvestInfoReponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.QueryCreditProjectDynamicReponseDTO;
import com.niiwoo.civet.trade.enums.ProjectStatusEnum;
import com.niiwoo.civet.trade.enums.credit.CreditLoanGuaranteeProjectStatusEnum;
import com.niiwoo.civet.trade.utils.SysStringUtils;
import com.niiwoo.tripod.base.utils.DateUtils;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 信用借.
 */
@Service
public class CreditService {

    /**
     * 金额的精度
     */
    static final int INVESTMENT_PRECISION_TWO = 2;
    @Autowired
    CreditProjectMapperExt creditProjectMapperExt;

    @Autowired
    CreditProjectRepaymentMapperExt creditProjectRepaymentMapperExt;

    @Autowired
    private CreditProjectDynamicMapperExt creditProjectDynamicMapperExt;

    @Autowired
    private CreditProjectInvestorMapperExt creditProjectInvestorMapperExt;

    @Autowired
    private CreditProjectGuaranteeMapperExt creditProjectGuaranteeMapperExt;

    @Autowired
    private ProjectContractMapperExt projectContractMapperExt;

    /**
     * 信用借-我的借款列表.
     *
     * @param dto
     * @return
     */
    public PageResponseDTO<MyCreditLoanResponseDTO> myCreditLoanQuery(MyCreditLoanRequestDTO dto) {
        PageResponseDTO<MyCreditLoanResponseDTO> result = new PageResponseDTO<>();

        int count = creditProjectMapperExt.selectMyCreditloanCount(dto.getUserId());
        List<MyCreditLoanResponseDTO> list = new ArrayList<>();
        List<MyCreditLoanResponseDTO> listForResult = new ArrayList<>();
        if (count > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(1970, 01, 01);
            Date date = calendar.getTime();//date就是你需要的时间
            list.addAll(creditProjectMapperExt.selectMyCreditloan(dto.getUserId()));
            for (MyCreditLoanResponseDTO project : list) {
                if (project.getPublishTime() == null) {
                    project.setPublishTime(date);
                }
                if (project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.REPAYMENT_FINISH.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.BAD_DEBT_REPAYMENT_FINISH.getCode())) {
                    //已结清(6,45)
                    project.setStatus(ProjectStatusEnum.FINISH.getStatus());
                    project.setProjectRemark(CreditLoanProjectRemarkEnum.FINISH_REMARK.getRemark());
                } else if (project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.OVERDUE.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.BAD_DEBT.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_SUCCESS.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.YELLOW_WARNING.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.RED_WARNING.getCode())) {
                    //还款中(43,44,5,41,42)
                    project.setStatus(ProjectStatusEnum.REPAYING.getStatus());
                    // 查询项目大于等于某期的还款计划列表
                    CreditProjectRepayment projectRepaymentForCondition = new CreditProjectRepayment();
                    projectRepaymentForCondition.setProjectId(project.getProjectId());
                    projectRepaymentForCondition.setCurrentPeriods(project.getCurrentPeriods());
                    List<CreditProjectRepayment> paymentListForAfter = creditProjectRepaymentMapperExt.selectByProjectIdAndPeriodsList(projectRepaymentForCondition);
                    //总待还金额
                    BigDecimal totalNeedPayAmount = getShouldPayAmount(project);
                    project.setPendingRepaymentTotalAmount(totalNeedPayAmount);
                    project.setProjectRemark(CreditLoanProjectRemarkEnum.REPAYING_REMARK.getRemark());
                    for (CreditProjectRepayment creditProjectRepayment : paymentListForAfter) {
                        if (creditProjectRepayment.getCurrentPeriods().equals(project.getTotalPeriods())) {
                            //项目到期时间
                            project.setRefundDate(creditProjectRepayment.getRefundDate());
                            break;
                        }
                    }
                } else if (project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.GUARANTEE_NOT_PASS.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_FAILURE.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_FAILURE_MANUAL.getCode())
                        || project.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.INVESTIGATE_NOT_PASS.getCode())) {
                    //流标(32,33,34,31)
                    project.setStatus(ProjectStatusEnum.MISCARRY.getStatus());
                } else {
                    project.setStatus((byte) 99);
                }
            }
            // 联合排序
            Comparator<MyCreditLoanResponseDTO> comparatorByStatus = (h1, h2) -> h1.getStatus().compareTo(h2.getStatus());
            Comparator<MyCreditLoanResponseDTO> comparatorByPublishTime = (h1, h2) -> h1.getPublishTime().compareTo(h2.getPublishTime());
            list.sort(comparatorByStatus.thenComparing(comparatorByPublishTime.reversed()));
            List<MyCreditLoanResponseDTO> listForSorted = list;
            int fromIndex = dto.getOffset();
            int toIndex = dto.getPageSize() * dto.getPageNumber();
            if (listForSorted.size() >= fromIndex) {
                if (listForSorted.size() < toIndex) {
                    toIndex = listForSorted.size();
                }
                listForResult = listForSorted.subList(fromIndex, toIndex);// listTemp是分段处理逻辑的参数
            }

        }
        result.measureTotalPage(count, dto.getPageSize());
        result.setItems(listForResult);

        return result;
    }

    private BigDecimal getShouldPayAmount(MyCreditLoanResponseDTO project) {
        CreditSumProjectRepayment creditSumProjectRepayment = creditProjectRepaymentMapperExt.selectSumByProjectId(project.getProjectId());
        BigDecimal refundInterest = BigDecimal.ZERO;
        CreditProjectRepayment creditProjectRepayment = creditProjectRepaymentMapperExt.selectFirstPeriodBadDebt(project.getProjectId());//坏账第一期数据
        CreditSumProjectRepayment badDebtSumProjectRepayment = creditProjectRepaymentMapperExt.selectSumByBadDebt(project.getProjectId());//坏账数据总计
        BigDecimal costAmount = creditSumProjectRepayment.getCostAmountSum().subtract(creditSumProjectRepayment.getRealCostAmountSum()); // 待还款本金
        if ((creditProjectRepayment != null) || (badDebtSumProjectRepayment != null)) {
            BigDecimal badDebtInterestSum = badDebtSumProjectRepayment.getRefundInterestSum().subtract(badDebtSumProjectRepayment.getRealRefundInterestSum());//坏账的利息
            //坏账待还款的利息=总的待还款利息-坏账状态的总待还利息+坏账状态的第一期的待还利息
            refundInterest = creditSumProjectRepayment.getRefundInterestSum().subtract(creditSumProjectRepayment.getRealRefundInterestSum())
                    .subtract(badDebtInterestSum).add(creditProjectRepayment.getRefundInterest().subtract(creditProjectRepayment.getRealRefundInterest())); // 待还款利息
        } else {
            refundInterest = creditSumProjectRepayment.getRefundInterestSum().subtract(creditSumProjectRepayment.getRealRefundInterestSum());
        }

        BigDecimal platformManagerFee = creditSumProjectRepayment.getPlatformManagerFeeSum().subtract(creditSumProjectRepayment.getRepaidPlatformManagerFeeSum()); // 待还平台管理费
        BigDecimal dunningServiceFee = creditSumProjectRepayment.getDunningServiceFeeSum().subtract(creditSumProjectRepayment.getRepaidDunningServiceFeeSum()); // 待还催收服务费
        BigDecimal totalPenalty = project.getCurrentPenalty().setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP); // 待还罚息
        // 本期待还款金 = 待还款本金 + 待还款利息 + 待还平台管理费 + 待还催收服务费 + 待还罚息
        BigDecimal totalAmount = costAmount.add(refundInterest).add(platformManagerFee).add(dunningServiceFee).add(totalPenalty);
        return totalAmount;
    }

    @Getter
    @AllArgsConstructor
    public enum CreditLoanProjectRemarkEnum {
        FINISH_REMARK(ProjectStatusEnum.FINISH.getStatus(), "还款已结清，让你的信用更有价值，请继续保持良好信用。"),
        REPAYING_REMARK(ProjectStatusEnum.REPAYING.getStatus(), "请联系客服进行还款，本项目已暂停充值账户还款");

        private Byte projectStatus;
        private String remark;

    }

    /**
     * 信用借查询还款记录
     *
     * @param projectId
     * @return
     */
    public QueryCreditProjectDynamicReponseDTO queryProjectDynamic(Long projectId, String userId, Long opId, Byte type) {
        Assert.notNull(projectId, "queryProjectDynamic projectId is null");
        Assert.notNull(projectId, "queryProjectDynamic userId is null");
        QueryCreditProjectDynamicReponseDTO result = new QueryCreditProjectDynamicReponseDTO();
        List<CreditProjectDynamicReponseDTO> projectDynamicReponseDTOList = new ArrayList<CreditProjectDynamicReponseDTO>();
        List<CreditProjectDynamic> projectDynamicList = creditProjectDynamicMapperExt.queryCreditProjectDynamicList(projectId, userId, opId, type);
        CreditSumProjectRepayment creditSumProjectRepayment = creditProjectRepaymentMapperExt.selectSumByProjectId(projectId);

        if (projectDynamicList != null) {
            for (CreditProjectDynamic projectDynamic : projectDynamicList) {
                if (projectDynamic != null) {
                    CreditProjectDynamicReponseDTO projectDynamicReponseDTO = new CreditProjectDynamicReponseDTO();
                    projectDynamicReponseDTO.setId(projectDynamic.getId());
                    projectDynamicReponseDTO.setProjectId(projectDynamic.getProjectId());
                    projectDynamicReponseDTO.setUserId(projectDynamic.getUserId());
                    projectDynamicReponseDTO.setOpId(projectDynamic.getOpId());
                    projectDynamicReponseDTO.setType(projectDynamic.getType());
                    projectDynamicReponseDTO.setDescription(projectDynamic.getDescription());
                    projectDynamicReponseDTO.setCreateTime(DateFormatUtils.format(projectDynamic.getCreatetime(),
                            DatePatternConstant.YYYY_MM_DD_HH_MM_SS));
                    projectDynamicReponseDTOList.add(projectDynamicReponseDTO);
                }
            }
        }
        CreditProject creditProject = creditProjectMapperExt.selectByPrimaryKey(projectId);
        String lastDescription = "";
        if (creditProject != null) {
            //投资记录
            if (type == 3) {
                lastDescription = "";
            }
            //担保记录
            if (type == 2) {
                String totalAmountString = "";
                CreditProjectGuarantee creditProjectGuarantee = creditProjectGuaranteeMapperExt.selectByPrimaryKey(opId);
                if (creditProjectGuarantee != null) {
                    //待垫付本金
                    BigDecimal pendingPaymentAdvanceAmount = creditProjectGuarantee.getAdvanceAmount().subtract(creditProjectGuarantee.getRealAdvanceAmount());
                    //待缴纳滞纳金
                    BigDecimal pendingPaymentOverdueFine = creditProjectGuarantee.getOverdueFine();
                    if ((pendingPaymentAdvanceAmount.add(pendingPaymentOverdueFine)).compareTo(BigDecimal.ZERO) != 0) {
                        totalAmountString = "剩余待垫付" + (pendingPaymentAdvanceAmount.add(pendingPaymentOverdueFine)) + "元，";
                    }
                    if (pendingPaymentAdvanceAmount.compareTo(BigDecimal.ZERO) != 0) {
                        totalAmountString = totalAmountString + "其中待垫付本金" + pendingPaymentAdvanceAmount + "元，";
                    }
                    //还款中状态
                    if (creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_SUCCESS.getCode())) {
                        lastDescription = "还款中：还款中状态无法及时更新，请到期联系客服查询，借款人还款后担保本金和收益会发放到银行卡。";
                    } else if (creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.OVERDUE.getCode())) {
                        //逾期状态
                        lastDescription = "逾期待还款：借款人还款已逾期，请尽快联系客服进行垫付。";

                        if (pendingPaymentOverdueFine != null && pendingPaymentOverdueFine.compareTo(BigDecimal.ZERO) != 0) {

                            lastDescription = lastDescription + totalAmountString + "待缴纳滞纳金" + pendingPaymentOverdueFine + "元。";

                        } else {
                            lastDescription = lastDescription + totalAmountString;
                        }
                        lastDescription = lastDescription.substring(0, lastDescription.length() - 1) + "。";
                    }
                }
            }
            if (creditSumProjectRepayment != null) {
                BigDecimal refundInterest = BigDecimal.ZERO;
                CreditProjectRepayment creditProjectRepayment = creditProjectRepaymentMapperExt.selectFirstPeriodBadDebt(projectId);//坏账第一期数据
                CreditSumProjectRepayment badDebtSumProjectRepayment = creditProjectRepaymentMapperExt.selectSumByBadDebt(projectId);//坏账数据总计
                BigDecimal costAmount = creditSumProjectRepayment.getCostAmountSum().subtract(creditSumProjectRepayment.getRealCostAmountSum()); // 待还款本金
                if ((creditProjectRepayment != null) || (badDebtSumProjectRepayment != null)) {
                    BigDecimal badDebtInterestSum = badDebtSumProjectRepayment.getRefundInterestSum().subtract(badDebtSumProjectRepayment.getRealRefundInterestSum());//坏账的利息
                    //坏账待还款的利息=总的待还款利息-坏账状态的总待还利息+坏账状态的第一期的待还利息
                    refundInterest = creditSumProjectRepayment.getRefundInterestSum().subtract(creditSumProjectRepayment.getRealRefundInterestSum())
                            .subtract(badDebtInterestSum).add(creditProjectRepayment.getRefundInterest().subtract(creditProjectRepayment.getRealRefundInterest())); // 待还款利息
                } else {
                    refundInterest = creditSumProjectRepayment.getRefundInterestSum().subtract(creditSumProjectRepayment.getRealRefundInterestSum());
                }

                BigDecimal platformManagerFee = creditSumProjectRepayment.getPlatformManagerFeeSum().subtract(creditSumProjectRepayment.getRepaidPlatformManagerFeeSum()); // 待还平台管理费
                BigDecimal dunningServiceFee = creditSumProjectRepayment.getDunningServiceFeeSum().subtract(creditSumProjectRepayment.getRepaidDunningServiceFeeSum()); // 待还催收服务费
                BigDecimal totalPenalty = creditProject.getCurrentPenalty().setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP); // 待还罚息
                // 本期待还款金 = 待还款本金 + 待还款利息 + 待还平台管理费 + 待还催收服务费 + 待还罚息
                BigDecimal totalAmount = costAmount.add(refundInterest).add(platformManagerFee).add(dunningServiceFee).add(totalPenalty);

                //还款记录
                if (type == 4) {
                    String repaymentString = "";

                    lastDescription = "请尽快联系客服进行还款。";

                    if (totalAmount.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = "剩余待还款" + totalAmount + "元，";
                    }
                    if (costAmount.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "其中本金" + costAmount + "元，";
                    }
                    if (refundInterest.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "利息" + refundInterest + "元，";
                    }
                    if (totalPenalty.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "罚息" + totalPenalty + "元，";
                    }
                    if (platformManagerFee.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "平台管理费" + platformManagerFee + "元，";
                    }
                    if (dunningServiceFee.compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "催收服务费" + dunningServiceFee + "元，";
                    }
                    if (creditProject.getGuaranteeFee().compareTo(BigDecimal.ZERO) != 0) {
                        repaymentString = repaymentString + "担保服务费" + creditProject.getGuaranteeFee().setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP) + "元。";
                    }
                    lastDescription = lastDescription + repaymentString;
                    lastDescription = lastDescription.substring(0, lastDescription.length() - 1) + "。";
                }
            }
        }
        result.setProjectId(projectId);
        result.setCreditProjectDynamicReponseDTOSList(projectDynamicReponseDTOList);
        result.setLastDescription(lastDescription);
        return result;
    }

    /**
     * 信用借查询投资记录
     *
     * @param requestDTO
     * @return
     */
    public PageResponseDTO<QueryCreditInvestInfoReponseDTO> queryCreditProjectInfoList(CreditLoanInvestProjectRequestDTO requestDTO) {

        PageResponseDTO<QueryCreditInvestInfoReponseDTO> pageResult = new PageResponseDTO<QueryCreditInvestInfoReponseDTO>();
        List<QueryCreditInvestInfoReponseDTO> result = new ArrayList<>();
        // 增加分页参数
        int offset = (requestDTO.getPageNumber() - 1) * requestDTO.getPageSize();
        int rows = requestDTO.getPageSize();
        List<CreditProjectInvestor> infoList = creditProjectInvestorMapperExt.selectByUserId(requestDTO.getUserId(), offset, rows);
        int count = creditProjectInvestorMapperExt.selectMyInvestCount(requestDTO.getUserId());
        if (count > 0) {
            for (CreditProjectInvestor creditProjectInvestor : infoList) {
                if (creditProjectInvestor != null) {
                    QueryCreditInvestInfoReponseDTO InfoReponseDTO = new QueryCreditInvestInfoReponseDTO();
                    CreditProject creditProject = creditProjectMapperExt.selectByPrimaryKey(creditProjectInvestor.getProjectId());
                    if (creditProject != null) {
                        InfoReponseDTO.setId(creditProjectInvestor.getId());
                        InfoReponseDTO.setProjectId(creditProject.getProjectId());
                        InfoReponseDTO.setBorrowerUserId(creditProject.getBorrowUserId());
                        InfoReponseDTO.setBorrowerGender(creditProject.getBorrowSex());
                        InfoReponseDTO.setBorrowerHeadImage(creditProject.getBorrowHeadImg());
                        InfoReponseDTO.setBorrowerNickName(creditProject.getBorrowNickName());
                        InfoReponseDTO.setBorrowRate(creditProject.getBorrowRate());
                        InfoReponseDTO.setBorrowAmount(creditProject.getContractAmount());
                        InfoReponseDTO.setDeadLine(creditProject.getDeadline());
                        InfoReponseDTO.setTitle(creditProject.getTitle());
                        if (creditProject.getFullSuccessTime() != null) {
                            InfoReponseDTO.setFullSuccessDate(DateFormatUtils.format(creditProject.getFullSuccessTime(),
                                    DatePatternConstant.YYYY_MM_DD_HH_MM));
                        } else {
                            InfoReponseDTO.setFullSuccessDate("");
                        }
                        //发布时间
                        InfoReponseDTO.setCreateTime(DateFormatUtils.format(creditProject.getCreateTime(),
                                DatePatternConstant.YYYY_MM_DD_HH_MM));
                        BigDecimal investNumber = new BigDecimal(creditProjectInvestor.getInveNumber().intValue());
                        InfoReponseDTO.setInvestedAmount(investNumber.multiply(creditProjectInvestor.getAmountPer()));
                        InfoReponseDTO.setLoanCity(creditProject.getLoanCity());
                        InfoReponseDTO.setLoanArea(creditProject.getLoanArea());
//                        InfoReponseDTO.setRevenue(creditProjectInvestor.getRevenue());
                        InfoReponseDTO.setRevenue(creditProjectInvestor.getRealRevenue()); // 2018/02/24 by liming  数据迁移验证bug修改:[信用借投资记录]已流标项目实际收益应该为0或者空
                        //流标
                        if (creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.GUARANTEE_NOT_PASS.getCode())
                                || creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_FAILURE.getCode())
                                || creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.LOAN_FAILURE_MANUAL.getCode())
                                || creditProject.getProjectStatus().equals(CreditLoanGuaranteeProjectStatusEnum.INVESTIGATE_NOT_PASS.getCode())) {
                            InfoReponseDTO.setStatus(ProjectStatusEnum.MISCARRY.getStatus());
                        }
                        //已结清(投资人除了流标的状态，其他都为已结清)
                        else {
                            InfoReponseDTO.setStatus(ProjectStatusEnum.FINISH.getStatus());
                            InfoReponseDTO.setText("本次还款已结清，欢迎关注平台其他投资标的");

                        }
                        InfoReponseDTO.setContractUrl(creditProject.getContractUrl());

                        result.add(InfoReponseDTO);
                    }
                }
            }
            try {
                sort(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        pageResult.measureTotalPage(count, requestDTO.getPageSize());
        pageResult.setItems(result);
        pageResult.setTotalCount(count);
        return pageResult;
    }

    /**
     * 排序按照已结清>流标、再按满标或发布时间排序。
     */
    private void sort(List<QueryCreditInvestInfoReponseDTO> result) {
        Collections.sort(result, new Comparator<QueryCreditInvestInfoReponseDTO>() {
            @Override
            public int compare(QueryCreditInvestInfoReponseDTO o1, QueryCreditInvestInfoReponseDTO o2) {

                int flag = o1.getStatus().byteValue() - o2.getStatus().byteValue();

                if (flag > 0) {
                    return 1;
                } else if (flag == 0 && ProjectStatusEnum.FINISH.getStatus().equals(o1.getStatus())) {
                    int fullDate = DateUtils.compareDate(DateUtils.parseDateFromString(o1.getFullSuccessDate(), DatePatternConstant.YYYY_MM_DD_HH_MM),
                            DateUtils.parseDateFromString(o2.getFullSuccessDate(), DatePatternConstant.YYYY_MM_DD_HH_MM));
                    //已结清
                    if (fullDate > 0) {
                        return 1;
                    } else if (fullDate < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                } else if (flag == 0 && ProjectStatusEnum.MISCARRY.getStatus().equals(o1.getStatus())) {
                    int createDate = DateUtils.compareDate(DateUtils.parseDateFromString(o1.getCreateTime(), DatePatternConstant.YYYY_MM_DD_HH_MM),
                            DateUtils.parseDateFromString(o2.getCreateTime(), DatePatternConstant.YYYY_MM_DD_HH_MM));
                    //流标
                    if (createDate > 0) {
                        return 1;
                    } else if (createDate < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                } else if (flag < 0) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
    }

    /**
     * 信用借查询合同参数
     *
     * @param userId
     * @return
     */
    public QueryCreditContractReponseDTO queryCreditContractParms(Long projectId, String userId, byte type) {

        CreditProject creditProject = new CreditProject();
        switch (type) {
            case 1: // 借款人1，项目Contract = id
                creditProject = creditProjectMapperExt.selectProjectByUserIdAndProjectId(userId, projectId);
                break;
            case 2: // 担保人2
                CreditProjectGuarantee creditProjectGuarantee = new CreditProjectGuarantee();
                List<CreditProjectGuarantee> guaranteeList = creditProjectGuaranteeMapperExt.queryCreditProjectGuaranteeList(projectId, userId);
                if (null != guaranteeList && 0 < guaranteeList.size()) {
                    creditProjectGuarantee = guaranteeList.get(0);
                    creditProject = creditProjectMapperExt.selectByPrimaryKey(creditProjectGuarantee.getProjectId());
                }
                break;
            case 3: // 投资人3
                CreditProjectInvestor creditProjectInvestor = new CreditProjectInvestor();
                List<CreditProjectInvestor> investList = creditProjectInvestorMapperExt.selectByProjectIdAndUserId(projectId, userId);
                if (null != investList && 0 < investList.size()) {
                    creditProjectInvestor = investList.get(0);
                    creditProject = creditProjectMapperExt.selectByPrimaryKey(creditProjectInvestor.getProjectId());
                }
                break;
            default:
                break;
        }
        QueryCreditContractReponseDTO result = getContractContentShow(userId, creditProject);
        // 获取合同编号
        ProjectContract projectContract = projectContractMapperExt.queryProjectContractByUserIdAndProjectIdAndContractType(userId, creditProject.getProjectId(), type);
        if(projectContract != null)
            result.setContractNo(projectContract.getContractNo());
        return result;
    }

    public QueryCreditContractReponseDTO getContractContentShow(String userId, CreditProject creditProject) {
        QueryCreditContractReponseDTO result = new QueryCreditContractReponseDTO();
        List<GuaranteeUserDTO> guaranteeInfoList = new ArrayList<GuaranteeUserDTO>();
        List<InvestUserDTO> investInfoList = new ArrayList<InvestUserDTO>();
        List<CreditProjectInvestor> investList = creditProjectInvestorMapperExt.selectByProjectId(creditProject.getProjectId());
        List<CreditProjectGuarantee> guaranteeList = creditProjectGuaranteeMapperExt.getGuaranteesByProjectId(creditProject.getProjectId());
        if (investList != null) {
            for (CreditProjectInvestor creditProjectInvestor : investList) {
                if (creditProjectInvestor != null) {
                    InvestUserDTO investUserDTO = new InvestUserDTO();
                    investUserDTO.setInvestId(creditProjectInvestor.getInvestorUserId());
                    if (!userId.equals(creditProjectInvestor.getInvestorUserId())) {
                        String encryptInvestorRealName = SysStringUtils.encryptionRealName(creditProjectInvestor.getInvestorRealName(), 1);
                        investUserDTO.setInvestName(encryptInvestorRealName);
                    } else {
                        investUserDTO.setInvestName(creditProjectInvestor.getInvestorRealName());
                    }

                    if (creditProjectInvestor.getInveNumber() != null && creditProjectInvestor.getAmountPer() != null) {
                        BigDecimal investNumber = new BigDecimal(creditProjectInvestor.getInveNumber().intValue());
                        BigDecimal investAmount = investNumber.multiply(creditProjectInvestor.getAmountPer());
                        //投资金额
                        investUserDTO.setInvestAmount(investAmount);
                    }
                    investInfoList.add(investUserDTO);
                }
            }
        }
        if (guaranteeList != null) {
            for (CreditProjectGuarantee creditProjectGuarantee : guaranteeList) {
                if (creditProjectGuarantee != null) {
                    GuaranteeUserDTO guaranteeUserDTO = new GuaranteeUserDTO();
                    guaranteeUserDTO.setGuaranteeId(creditProjectGuarantee.getGuaranteeUserId());
                    if (!userId.equals(creditProjectGuarantee.getGuaranteeUserId())) {
                        String encryptGuaranteeRealName = SysStringUtils.encryptionRealName(creditProjectGuarantee.getGuaranteeRealName(), 1);
                        guaranteeUserDTO.setGuaranteeName(encryptGuaranteeRealName);
                    } else {
                        guaranteeUserDTO.setGuaranteeName(creditProjectGuarantee.getGuaranteeRealName());
                    }
                    //担保比例
                    if (null != creditProject.getContractAmount() && null != creditProjectGuarantee.getAmount()) {
                        BigDecimal guaranteeRate = creditProjectGuarantee.getAmount().divide(creditProject.getContractAmount(), 2, BigDecimal.ROUND_HALF_DOWN);
                        guaranteeUserDTO.setGuaranteeOfRate(guaranteeRate);
                    }
                    guaranteeInfoList.add(guaranteeUserDTO);
                }
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        if (creditProject != null) {
            result.setBorrowId(creditProject.getBorrowUserId());
            result.setBorrowAmount(creditProject.getContractAmount());
            if (!userId.equals(creditProject.getBorrowUserId())) {
                String encryptBorrowRealName = SysStringUtils.encryptionRealName(creditProject.getBorrowRealName(), 1);
                result.setBorrowName(encryptBorrowRealName);
            } else {
                result.setBorrowName(creditProject.getBorrowRealName());
            }
            result.setDeadline(creditProject.getDeadline());
            if (creditProject.getServiceFee() != null) {
                //平台服务费
                BigDecimal platformServiceAmount = creditProject.getServiceFee().setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP);
                result.setBorrowPlatformServiceFee(platformServiceAmount);
            }
            //罚息日率
            result.setPenaltyRate(creditProject.getPenaltyRate().divide(new BigDecimal("100")));
            //支付担保人担保费
            if (creditProject.getContractAmount() != null) {
                BigDecimal guarantorServiceAmount = creditProject.getContractAmount().multiply(creditProject.getGuaranteeRate())
                        .divide(new BigDecimal(100));
                result.setGuaranteeFee(guarantorServiceAmount.setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP));
            }

            if (null != creditProject.getFullSuccessTime()) {
                //合同生效时间
                result.setEffectiveDate(sdf.format(creditProject.getFullSuccessTime()));
                //还款时间
                result.setRefundDate(getContractRepaymentDate(creditProject.getProjectId()));
            }
            //车马费
            if (creditProject.getHorseFee() != null) {
                result.setHorseFee(creditProject.getHorseFee().setScale(INVESTMENT_PRECISION_TWO, BigDecimal.ROUND_HALF_UP));
            }
            result.setRepaymentType(creditProject.getRepaymentType());
            String repaymentTypeName = "";
            if (creditProject.getRepaymentType() != null) {
                switch (creditProject.getRepaymentType()) {
                    case 1:
                        repaymentTypeName = CreditRepaymentTypeEnum.REPAY_PRINCIPAL_INTEREST_AT_TERM.getDesc();
                        break;
                    case 2:
                        repaymentTypeName = CreditRepaymentTypeEnum.REPAY_PRINCIPAL_AT_TERM.getDesc();
                        break;
                    case 5:
                        repaymentTypeName = CreditRepaymentTypeEnum.AVERAGE_CAPITAL_PLUS_INTEREST.getDesc();
                        break;
                    default:
                        repaymentTypeName = "未知";
                        break;
                }
            }
            result.setRepaymentTypeName(repaymentTypeName);
            result.setYearRate(creditProject.getBorrowRate().divide(new BigDecimal("100")));
        }
        result.setGuaranteeUserList(guaranteeInfoList);
        result.setInvestUserList(investInfoList);


        return result;
    }

    /**
     * 获取合同还款日期
     *
     * @param projectId
     * @return
     */
    public String getContractRepaymentDate(Long projectId) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        CreditProjectRepayment creditProjectRepayment = creditProjectRepaymentMapperExt.selectLastPeriodsByProjectId(projectId);

        if (creditProjectRepayment.getRefundDate() != null) {
            String refundDate = sdf.format(creditProjectRepayment.getRefundDate());
            return refundDate;
        }
        return "";
    }

    /**
     * 判断投资用户是否存在信用借(1，存在，0不存在)
     */
    public int queryCreditInvestorProject(String userId) {
        int count = creditProjectInvestorMapperExt.selectMyInvestCount(userId);
        if (count == 0) {
            return 0;
        } else {
            return 1;
        }
    }
}


